"""
RedFire Framework 基础应用示例

展示如何使用 RedFire Framework 创建一个完整的微服务应用。
"""

import asyncio
from fastapi import FastAPI, HTTPException
from redfire_framework import (
    framework,
    event_handler,
    cache,
    retry_on_failure,
    circuit_breaker,
    startup_handler,
    shutdown_handler
)


# 创建 FastAPI 应用
app = FastAPI(
    title="RedFire 示例应用",
    description="展示 RedFire Framework 功能",
    version="1.0.0",
    lifespan=framework.lifespan
)


# 示例事件
class UserRegistered:
    def __init__(self, user_id: str, email: str):
        self.user_id = user_id
        self.email = email


# 事件处理器示例
@event_handler("user.registered")
async def send_welcome_email(event: UserRegistered):
    """用户注册后发送欢迎邮件"""
    print(f"发送欢迎邮件给用户 {event.user_id}: {event.email}")


@event_handler("user.registered")
async def create_user_profile(event: UserRegistered):
    """用户注册后创建用户档案"""
    print(f"为用户 {event.user_id} 创建档案")


# 缓存示例
@cache(ttl=300, key_prefix="user")
async def get_user_info(user_id: str) -> dict:
    """获取用户信息（带缓存）"""
    # 模拟数据库查询
    await asyncio.sleep(0.1)
    return {
        "user_id": user_id,
        "name": f"User {user_id}",
        "email": f"user{user_id}@example.com"
    }


# 重试和熔断示例
@retry_on_failure(max_attempts=3)
@circuit_breaker(failure_threshold=5, recovery_timeout=30)
async def external_api_call(data: dict) -> dict:
    """调用外部 API（带重试和熔断保护）"""
    # 模拟外部 API 调用
    await asyncio.sleep(0.2)
    
    # 模拟偶尔失败
    import random
    if random.random() < 0.2:
        raise HTTPException(status_code=500, detail="外部服务暂时不可用")
    
    return {"status": "success", "data": data}


# API 端点
@app.get("/")
async def root():
    """根端点"""
    return {"message": "RedFire Framework 示例应用"}


@app.get("/users/{user_id}")
async def get_user(user_id: str):
    """获取用户信息"""
    user_info = await get_user_info(user_id)
    return user_info


@app.post("/users/{user_id}/register")
async def register_user(user_id: str, email: str):
    """注册用户"""
    # 发布用户注册事件
    event = UserRegistered(user_id=user_id, email=email)
    await framework.event_bus.publish("user.registered", event)
    
    return {"message": f"用户 {user_id} 注册成功"}


@app.post("/external-call")
async def call_external(data: dict):
    """调用外部服务"""
    try:
        result = await external_api_call(data)
        return result
    except HTTPException as e:
        return {"error": e.detail}


@app.get("/health")
async def health_check():
    """健康检查端点"""
    health_status = await framework.health.check()
    return {
        "status": health_status.status.value,
        "checks": {
            name: {
                "status": check.status.value,
                "message": check.message,
                "last_check": check.last_check.isoformat() if check.last_check else None
            }
            for name, check in health_status.checks.items()
        }
    }


@app.get("/metrics")
async def get_metrics():
    """获取应用指标"""
    metrics = framework.metrics.get_all_metrics()
    return metrics


# 生命周期事件处理
@startup_handler
async def app_startup():
    """应用启动时执行"""
    print("🚀 RedFire 示例应用启动完成")
    
    # 初始化一些指标
    framework.metrics.increment_counter("app.started")


@shutdown_handler
async def app_shutdown():
    """应用关闭时执行"""
    print("🛑 RedFire 示例应用正在关闭")
    
    # 记录关闭指标
    framework.metrics.increment_counter("app.stopped")


# 中间件示例
@app.middleware("http")
async def custom_middleware(request, call_next):
    """自定义中间件示例"""
    # 记录请求指标
    framework.metrics.increment_counter("requests.total")
    
    # 记录请求开始时间
    import time
    start_time = time.time()
    
    # 处理请求
    response = await call_next(request)
    
    # 记录请求处理时间
    process_time = time.time() - start_time
    framework.metrics.observe_histogram("request.duration", process_time)
    
    return response


if __name__ == "__main__":
    import uvicorn
    
    # 配置框架
    config = {
        "cache": {
            "backend": "memory",  # 使用内存缓存
            "default_ttl": 300
        },
        "metrics": {
            "enabled": True,
            "prometheus_port": 8001
        },
        "health": {
            "enabled": True
        },
        "logging": {
            "level": "INFO",
            "format": "structured"
        }
    }
    
    # 异步初始化框架
    async def init_framework():
        await framework.initialize(config)
    
    asyncio.run(init_framework())
    
    # 启动应用
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        log_level="info"
    )
